#include "Mcu.h"
#include "Uart.h"
#include "CrcUtility.h"

Mcu *Mcu::getInstance()
{
    static Mcu singleton{};
    return &singleton;
}

void Mcu::init()
{
    Uart::getInstance()->init();
    QObject::connect(Protocol::getInstance(), &Protocol::parseCompleteSignal, this, &Mcu::handle);
}

void Mcu::systemShutdownMessage()
{
    Frame frame;
    uint8_t buffer[10] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = SystemShutdown;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

static bool m_state = true;
void Mcu::touchSoundBeepMessage()
{
    /* 加快程序运行速度 */
    uint8_t buffer[] = {0x69, 0x00, 0x04, 0x00, 0x02, 0x00, 0x17, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x96};
    if (m_state)
        Uart::getInstance()->sendData(buffer, 15);
}

void Mcu::setTouchSoundBeepStateMessage(bool state)
{
    m_state = state;
}

void Mcu::setSpiFlashSwitchMessage(uint8_t state)
{
    Frame frame;
    uint8_t buffer[10] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = SwitchSpiFlash;
    frame.datalLength = 0x01;
    frame.data = buffer;
    buffer[0] = state;
    Protocol::getInstance()->send(&frame);
}

void Mcu::setStripeCalibrationMessage(uint8_t level)
{
    Frame frame;
    uint8_t buffer[10] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = StripeCalibration;
    frame.datalLength = 0x01;
    frame.data = buffer;
    buffer[0] = level;
    Protocol::getInstance()->send(&frame);
}

void Mcu::setSensorCalibrationMessage(uint8_t level)
{
    Frame frame;
    uint8_t buffer[10] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = SensorCalibration;
    frame.datalLength = 0x01;
    frame.data = buffer;
    buffer[0] = level;
    Protocol::getInstance()->send(&frame);
}

void Mcu::readMainframeMcuVersionMessage()
{
    Frame frame;
    uint8_t buffer[1] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = ReadMainframeMcuSoftwareVersion;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

/**
 * @brief Mcu::OPenOrCloseAJL
 * @param open true-打开 false-关闭
 */
void Mcu::OPenOrCloseAJL(bool open) {
    Frame frame;
    uint8_t buffer[1] = {0x00};
    buffer[0] = open?0X01:0X00;
    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = OpenOrCloseAJL;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::mainframeMcuUpdateJumpMessage()
{
    Frame frame;
    uint8_t buffer[1] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = MainframeMcuUpdateJump;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::mainframeMcuUpdateStartMessage()
{
    Frame frame;
    uint8_t buffer[1] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = MainframeMcuUpdateStart;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::mainframeMcuUpdateStopMessage(uint32_t size, uint8_t crc)
{
    Frame frame;
    uint8_t buffer[5] = {0x00};

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = MainframeMcuUpdateStop;
    frame.datalLength = 0x05;
    buffer[4] = (size >> 0) & 0xFF;
    buffer[3] = (size >> 8) & 0xFF;
    buffer[2] = (size >> 16) & 0xFF;
    buffer[1] = (size >> 24) & 0xFF;
    buffer[0] = crc;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::reportSensorState(bool connected) {
    Frame frame;
    uint8_t buffer[1] = {0x00};
    buffer[0] = connected?1:0;
    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = CurrentSensorTtype;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::reportSensorImageError() {
    Frame frame;
    uint8_t buffer[1] = {0x00};
    buffer[0] = 0;
    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = SensorImageERROR;
    frame.datalLength = 0x01;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::sendSensorRegisterOperation(SensorRegisterOperationPkg &pkg) {
    Frame frame;
    uint8_t *buffer = reinterpret_cast<uint8_t *>(&pkg);

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = SensorRegisterOperation;
    frame.datalLength = sizeof (SensorRegisterOperationPkg);
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

void Mcu::mainframeMcuUpdateResponseMessage(uint8_t *buffer, uint16_t size)
{
    Frame frame;

    frame.from = MainframeArm;
    frame.to = MainframeMcu;
    frame.commandCode = MainframeMcuUpdateResponse;
    frame.datalLength = size;
    frame.data = buffer;
    Protocol::getInstance()->send(&frame);
}

uint8_t Mcu::calculateCrc(uint8_t *data, int32_t length)
{
    return CrcUtility::getInstance()->calculateCrc8(data, length);
}

Mcu::Mcu() {

}

void Mcu::handle(Frame *frame) {
    switch (frame->commandCode) {
    case ReportKeyValue:
        qDebug()<<"key val:"<<frame->data[0];
        emit reportKeyValueSignal(frame->data[0]);
        break;

    case ReadMainframeMcuSoftwareVersion:
        readMainframeMcuVersionAction(frame);
        break;

    case MainframeMcuUpdateRequest:
        mainframeMcuUpdateRequestAction(frame);
        break;
    case CurrentSensorTtype :
        qDebug()<<"sensor type:"<<frame->data[0];
        emit reportMcuCurrSensorType(frame->data[0]);
        break;
    case SensorRegisterOperation:
        qDebug()<<"reportSensorRegisterValue:"<<frame->data[0];
        emit reportSensorRegisterValue(frame->data[0]);

        break;
    }
}
